package com.violet.myorm.core.execute;

import com.violet.myorm.core.source.Source;
import com.violet.myorm.core.sql.QuerySql;
import com.violet.myorm.core.sql.Sql;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.function.Function;

@Slf4j
public abstract class BaseExecute {
    protected <E> E executeQuery(QuerySql querySql, List<Object> params, Function<ResultSet, E> function) {
        try (
            Connection connection = Source.getConnection();
            PreparedStatement statement = connection.prepareStatement(querySql.getSql())
        ) {
            for (int i = 0; i < params.size(); i++) statement.setObject(i + 1, params.get(i));
            //log.warn("{}", statement);
            return function.apply(statement.executeQuery());
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    protected int executeDelete(Sql sql, List<Object> params) {
        try (
            Connection connection = Source.getConnection();
            PreparedStatement statement = connection.prepareStatement(sql.getSql())
        ) {
            for (int i = 0; i < params.size(); i++) statement.setObject(i + 1, params.get(i));
            //log.warn("{}", statement);
            return statement.executeUpdate();
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    protected int executeUpdate(Sql sql, List<Object> values, List<Object> params) {
        try (
            Connection connection = Source.getConnection();
            PreparedStatement statement = connection.prepareStatement(sql.getSql())
        ) {
            for (int i = 0; i < values.size(); i++) statement.setObject(i + 1, values.get(i));
            for (int i = values.size(); i < values.size() + params.size(); i++) statement.setObject(i + 1, params.get(i - values.size()));

            // log.warn("{}", statement);

            return statement.executeUpdate();
        }
        catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
